home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / mkmsgsrc.zip / MKMSGFID.PAS < prev    next >
Pascal/Delphi Source File  |  1992-09-19  |  34KB  |  1,377 lines

  1. Unit MKMsgFid;       {Fido *.Msg Unit}
  2.  
  3. {$I MKB.Def}
  4.  
  5. Interface
  6.  
  7. Uses MKGlobT, MKMsgAbs,
  8. {$IFDEF WINDOWS}
  9.   Strings, WinDos;
  10. {$ELSE}
  11.   Dos;
  12. {$ENDIF}
  13.  
  14.  
  15. Type FMsgType = Record
  16.   MsgFile: File;
  17.   TextCtr: LongInt;
  18.   MsgName: String[13];
  19.   Error: Word;
  20.   NetMailPath: String[128];
  21.   MsgChars: Array[0..33000] of Char;
  22.   Dest: AddrType;
  23.   Orig: AddrType;
  24.   MsgStart: LongInt;
  25.   MsgEnd: LongInt;
  26.   MsgSize: Word;
  27.   DefaultZone: Word;
  28.   QDate: String[8];
  29.   QTime: String[5];
  30.   LastSoft: Boolean;
  31.   MsgDone: Boolean;
  32.   CurrMsg: LongInt;
  33.   SeekOver: Boolean;
  34.   {$IFDEF WINDOWS}
  35.   SR: TSearchRec;
  36.   {$ELSE}
  37.   SR: SearchRec;
  38.   {$ENDIF}
  39.   Name: String[35];
  40.   Handle: String[35];
  41.   End;
  42.  
  43.  
  44. Type FidoMsgObj = Object (AbsMsgObj)
  45.   FM: ^FMsgType;
  46.   Constructor Init;                      {Initialize FidoMsgOut}
  47.   Destructor Done; Virtual; {Done FidoMsgOut}
  48.   Procedure PutLong(L: LongInt; Position: Word); {Put long into msg}
  49.   Procedure PutWord(W: Word; Position: Word);  {Put word into msg}
  50.   Procedure PutByte(B: Byte; Position: Word);  {Put byte into msg}
  51.   Procedure PutNullStr(St: String; Position: Word);  {Put string & null into msg}
  52.   Procedure SetMsgPath(St: String); Virtual; {Set netmail path}
  53.   Function  GetHighMsgNum: LongInt; Virtual; {Get highest netmail msg number in area}
  54.   Procedure SetDest(Var Addr: AddrType); Virtual; {Set Zone/Net/Node/Point for Dest}
  55.   Procedure SetOrig(Var Addr: AddrType); Virtual; {Set Zone/Net/Node/Point for Orig}
  56.   Procedure SetFrom(Name: String); Virtual; {Set message from}
  57.   Procedure SetTo(Name: String); Virtual; {Set message to}
  58.   Procedure SetSubj(Str: String); Virtual; {Set message subject}
  59.   Procedure SetCost(SCost: Word); Virtual; {Set message cost}
  60.   Procedure SetRefer(SRefer: LongInt); Virtual; {Set message reference}
  61.   Procedure SetSeeAlso(SAlso: LongInt); Virtual; {Set message see also}
  62.   Procedure SetDate(SDate: String); Virtual; {Set message date}
  63.   Procedure SetTime(STime: String); Virtual; {Set message time}
  64.   Procedure SetLocal(LS: Boolean); Virtual; {Set local status}
  65.   Procedure SetRcvd(RS: Boolean); Virtual; {Set received status}
  66.   Procedure SetPriv(PS: Boolean); Virtual; {Set priveledge vs public status}
  67.   Procedure SetCrash(SS: Boolean); Virtual; {Set crash netmail status}
  68.   Procedure SetKillSent(SS: Boolean); Virtual; {Set kill/sent netmail status}
  69.   Procedure SetSent(SS: Boolean); Virtual; {Set sent netmail status}
  70.   Procedure SetFAttach(SS: Boolean); Virtual; {Set file attach status}
  71.   Procedure SetReqRct(SS: Boolean); Virtual; {Set request receipt status}
  72.   Procedure SetReqAud(SS: Boolean); Virtual; {Set request audit status}
  73.   Procedure SetRetRct(SS: Boolean); Virtual; {Set return receipt status}
  74.   Procedure SetFileReq(SS: Boolean); Virtual; {Set file request status}
  75.   Procedure DoString(Str: String); Virtual; {Add string to message text}
  76.   Procedure DoChar(Ch: Char); Virtual; {Add character to message text}
  77.   Procedure DoStringLn(Str: String); Virtual; {Add string and newline to msg text}
  78.   Function  WriteMsg: Word; Virtual;
  79.   Procedure SetDefaultZone(DZ: Word); Virtual; {Set default zone to use}
  80.   Procedure LineStart; Virtual; {Internal use to skip LF, ^A}
  81.   Function  GetChar: Char; Virtual;
  82.   Procedure CheckZone(ZoneStr: String); Virtual;
  83.   Procedure CheckPoint(PointStr: String); Virtual;
  84.   Procedure CheckLine(TStr: String); Virtual;
  85.   Function  CvtDate: Boolean; Virtual;
  86.   Function  BufferWord(i: Word):Word; Virtual;
  87.   Function  BufferByte(i: Word):Byte; Virtual;
  88.   Function  BufferNullString(i: Word; Max: Word): String; Virtual;
  89.   Procedure MsgStartUp; Virtual; {set up msg for reading}
  90.   Function  EOM: Boolean; Virtual; {No more msg text}
  91.   Function  GetString(MaxLen: Word): String; Virtual; {Get wordwrapped string}
  92.   Function  WasWrap: Boolean; Virtual; {Last line was soft wrapped no CR}
  93.   Procedure SeekFirst(MsgNum: LongInt); Virtual; {Seek msg number}
  94.   Procedure SeekNext; Virtual; {Find next matching msg}
  95.   Procedure SeekPrior; Virtual; {Seek prior matching msg}
  96.   Function  GetFrom: String; Virtual; {Get from name on current msg}
  97.   Function  GetTo: String; Virtual; {Get to name on current msg}
  98.   Function  GetSubj: String; Virtual; {Get subject on current msg}
  99.   Function  GetCost: Word; Virtual; {Get cost of current msg}
  100.   Function  GetDate: String; Virtual; {Get date of current msg}
  101.   Function  GetTime: String; Virtual; {Get time of current msg}
  102.   Function  GetRefer: LongInt; Virtual; {Get reply to of current msg}
  103.   Function  GetSeeAlso: LongInt; Virtual; {Get see also of current msg}
  104.   Function  GetMsgNum: LongInt; Virtual; {Get message number}
  105.   Procedure GetOrig(Var Addr: AddrType); Virtual; {Get origin address}
  106.   Procedure GetDest(Var Addr: AddrType); Virtual; {Get destination address}
  107.   Function  IsLocal: Boolean; Virtual; {Is current msg local}
  108.   Function  IsCrash: Boolean; Virtual; {Is current msg crash}
  109.   Function  IsKillSent: Boolean; Virtual; {Is current msg kill sent}
  110.   Function  IsSent: Boolean; Virtual; {Is current msg sent}
  111.   Function  IsFAttach: Boolean; Virtual; {Is current msg file attach}
  112.   Function  IsReqRct: Boolean; Virtual; {Is current msg request receipt}
  113.   Function  IsReqAud: Boolean; Virtual; {Is current msg request audit}
  114.   Function  IsRetRct: Boolean; Virtual; {Is current msg a return receipt}
  115.   Function  IsFileReq: Boolean; Virtual; {Is current msg a file request}
  116.   Function  IsRcvd: Boolean; Virtual; {Is current msg received}
  117.   Function  IsPriv: Boolean; Virtual; {Is current msg priviledged/private}
  118.   Function  IsDeleted: Boolean; Virtual; {Is current msg deleted}
  119.   Function  IsEchoed: Boolean; Virtual; {Msg should be echoed}
  120.   Function  GetMsgLoc: LongInt; Virtual; {Msg location}
  121.   Procedure SetMsgLoc(ML: LongInt); Virtual; {Msg location}
  122.   Procedure YoursFirst(Name: String; Handle: String); Virtual; {Seek your mail}
  123.   Procedure YoursNext; Virtual; {Seek next your mail}
  124.   Function  YoursFound: Boolean; Virtual; {Message found}
  125.   Procedure StartNewMsg; Virtual;
  126.   Function  OpenMsgBase: Word; Virtual;
  127.   Function  CloseMsgBase: Word; Virtual;
  128.   Function  CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word; Virtual;
  129.   Function  SeekFound: Boolean; Virtual;
  130.   Procedure SetMailType(MT: MsgMailType); Virtual; {Set message base type}
  131.   Function  GetSubArea: Word; Virtual; {Get sub area number}
  132.   Procedure ReWriteHdr; Virtual; {Rewrite msg header after changes}
  133.   Procedure DeleteMsg; Virtual; {Delete current message}
  134.   Function  NumberOfMsgs: LongInt; Virtual; {Number of messages}
  135.   Function  GetLastRead(UNum: LongInt): LongInt; Virtual; {Get last read for user num}
  136.   Procedure SetLastRead(UNum: LongInt; LR: LongInt); Virtual; {Set last read}
  137.   Procedure MsgTxtStartUp; Virtual; {Do message text start up tasks}
  138.   Function  GetTxtPos: LongInt; Virtual; {Get indicator of msg text position}
  139.   Procedure SetTxtPos(TP: LongInt); Virtual; {Set text position}
  140.   End;
  141.  
  142.  
  143. Type FidoMsgPtr = ^FidoMsgObj;
  144.  
  145. Function MonthStr(MoNo: Byte): String; {Return 3 char month name for month num}
  146. Function MonthNum(St: String):Word;
  147.  
  148.  
  149. Implementation
  150.  
  151. Uses MKFile, MKString, MKDos;
  152.  
  153.  
  154. Constructor FidoMsgObj.Init;
  155.   Begin
  156.   New(FM);
  157.   If FM = Nil Then
  158.     Begin
  159.     Fail;
  160.     Exit;
  161.     End;
  162.   FM^.NetMailPath := '';
  163.   FillChar(FM^.MsgChars, SizeOf(FM^.MsgChars), #0);
  164.   FM^.TextCtr := 190;
  165.   FM^.Dest.Zone := 0;
  166.   FM^.Orig.Zone := 0;
  167.   FM^.SeekOver := False;
  168.   FM^.DefaultZone := 1;
  169.   End;
  170.  
  171.  
  172. Destructor FidoMsgObj.Done;
  173.   Begin
  174.   Dispose(FM);
  175.   End;
  176.  
  177.  
  178. Procedure FidoMsgObj.PutLong(L: LongInt; Position: Word);
  179.   Var
  180.     i: Integer;
  181.  
  182.   Begin
  183.   i := 3;
  184.   While i >= 0 Do
  185.     Begin
  186.     FM^.MsgChars[Position + i] := Char(L and $ff);
  187.     L := L shr 8;
  188.     Dec(i);
  189.     End;
  190.   End;
  191.  
  192.  
  193. Procedure FidoMsgObj.PutWord(W: Word; Position: Word);
  194.   Begin
  195.   FM^.MsgChars[Position] := Char(Lo(W));
  196.   FM^.MsgChars[Position + 1] := Char(Hi(W));
  197.   End;
  198.  
  199.  
  200. Procedure FidoMsgObj.PutByte(B: Byte; Position: Word);
  201.   Begin
  202.   FM^.MsgChars[Position] := Char(B);
  203.   End;
  204.  
  205.  
  206.  
  207. Procedure FidoMsgObj.PutNullStr(St: String; Position: Word);
  208.   Var
  209.     i: Word;
  210.  
  211.   Begin
  212.   i := 1;
  213.   While i <= Length(St) Do
  214.     Begin
  215.     FM^.MsgChars[Position + i - 1] := St[i];
  216.     Inc(i);
  217.     End;
  218.   FM^.MsgChars[Position + Length(St)] := #0;
  219.   End;
  220.  
  221.  
  222. Procedure FidoMsgObj.SetMsgPath(St: String);
  223.   Begin
  224.   FM^.NetMailPath := Copy(St, 1, 110);
  225.   AddBackSlash(FM^.NetMailPath);
  226.   End;
  227.  
  228.  
  229. Function FidoMsgObj.GetHighMsgNum: LongInt;
  230.   Var
  231.   {$IFDEF WINDOWS}
  232.     SR: TSearchRec;
  233.     TStr: Array[0..128] of Char;
  234.   {$ELSE}
  235.     SR: SearchRec;
  236.   {$ENDIF}
  237.   TmpName: String[13];
  238.   TmpNum: Word;
  239.   Code: Word;
  240.   Highest: LongInt;
  241.  
  242.   Begin
  243.   Highest := 1;
  244.   {$IFDEF WINDOWS}
  245.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  246.   FindFirst(TStr, faReadOnly + faArchive, SR);
  247.   {$ELSE}
  248.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, SR);
  249.   {$ENDIF}
  250.   While DosError = 0 Do
  251.     Begin
  252.     {$IFDEF WINDOWS}
  253.     TmpName :=  StrPas(SR.Name);
  254.     {$ELSE}
  255.     TmpName := SR.Name;
  256.     {$ENDIF}
  257.     Val(Copy(TmpName, 1,  Pos('.', TmpName) - 1), TmpNum, Code);
  258.     If ((Code = 0) And (TmpNum > Highest)) Then
  259.       Highest := TmpNum;
  260.     FindNext(SR);
  261.     End;
  262.   GetHighMsgNum := Highest;
  263.   End;
  264.  
  265.  
  266. Function MonthStr(MoNo: Byte): String;
  267.   Begin
  268.   Case MoNo of
  269.     01: MonthStr := 'Jan';
  270.     02: MonthStr := 'Feb';
  271.     03: MonthStr := 'Mar';
  272.     04: MonthStr := 'Apr';
  273.     05: MonthStr := 'May';
  274.     06: MonthStr := 'Jun';
  275.     07: MonthStr := 'Jul';
  276.     08: MonthStr := 'Aug';
  277.     09: MonthStr := 'Sep';
  278.     10: MonthStr := 'Oct';
  279.     11: MonthStr := 'Nov';
  280.     12: MonthStr := 'Dec';
  281.     Else
  282.       MonthStr := '???';
  283.     End;
  284.   End;
  285.  
  286.  
  287. Procedure FidoMsgObj.SetDest(Var Addr: AddrType);
  288.   Begin
  289.   FM^.Dest := Addr;
  290.   PutWord(Addr.Net, 174);
  291.   PutWord(Addr.Node, 166);
  292.   If Addr.Point <> 0 Then
  293.     Begin
  294.     If ((FM^.TextCtr <> 190) And
  295.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  296.       DoChar(#13);
  297.     DoStringLn(#1 + 'TOPT ' + Long2Str(Addr.Point));
  298.     End;
  299.   If ((FM^.Orig.Zone <> 0)) Then
  300.     Begin
  301.     If ((FM^.TextCtr <> 190) And
  302.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  303.       DoChar(#13);
  304.     DoStringLn(#1 + 'INTL ' + AddrStr(FM^.Dest) + ' ' + AddrStr(FM^.Orig));
  305.     End;
  306.   End;
  307.  
  308.  
  309. Procedure FidoMsgObj.SetOrig(Var Addr: AddrType);
  310.   Begin
  311.   FM^.Orig := Addr;
  312.   PutWord(Addr.Net, 172);
  313.   PutWord(Addr.Node, 168);
  314.   If Addr.Point <> 0 Then
  315.     Begin
  316.     If ((FM^.TextCtr <> 190) And
  317.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  318.       DoChar(#13);
  319.     DoStringLn(#1 + 'FMPT ' + Long2Str(Addr.Point));
  320.     End;
  321.   If ((FM^.Dest.Zone <> 0)) Then
  322.     Begin
  323.     If ((FM^.TextCtr <> 190) And
  324.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  325.       DoChar(#13);
  326.     DoStringLn(#1 + 'INTL ' + AddrStr(FM^.Dest) + ' ' + AddrStr(FM^.Orig));
  327.     End;
  328.   End;
  329.  
  330.  
  331. Procedure FidoMsgObj.SetFrom(Name: String);
  332.   Begin
  333.   PutNullStr(Copy(Name, 1, 35),0);
  334.   End;
  335.  
  336.  
  337. Procedure FidoMsgObj.SetTo(Name: String);
  338.   Begin
  339.   PutNullStr(Copy(Name, 1, 35), 36);
  340.   End;
  341.  
  342.  
  343. Procedure FidoMsgObj.SetSubj(Str: String);
  344.   Begin
  345.   PutNullStr(Copy(Str, 1, 71), 72);
  346.   End;
  347.  
  348.  
  349. Procedure FidoMsgObj.SetCost(SCost: Word);
  350.   Begin
  351.   PutWord(SCost, 170);
  352.   End;
  353.  
  354.  
  355. Procedure FidoMsgObj.SetRefer(SRefer: LongInt);
  356.   Begin
  357.   PutWord(SRefer, 184);
  358.   End;
  359.  
  360.  
  361. Procedure FidoMsgObj.SetSeeAlso(SAlso: LongInt);
  362.   Begin
  363.   PutWord(SAlso, 188);
  364.   End;
  365.  
  366.  
  367. Procedure FidoMsgObj.SetDate(SDate: String);
  368.   Var
  369.     TempNum: Word;
  370.     Code: Word;
  371.     TmpStr: String[20];
  372.  
  373.   Begin
  374.   FM^.QDate := Copy(SDate,1,8);
  375.   Val(Copy(SDate,1,2),TempNum, Code);
  376.   TmpStr := Copy(SDate,4,2) + ' ' + MonthStr(TempNum) + ' ' +
  377.     Copy(SDate,7,2) + '  ';
  378.   For TempNum := 1 to 11 Do
  379.     FM^.MsgChars[TempNum + 143] := TmpStr[TempNum];
  380.   End;
  381.  
  382.  
  383. Procedure FidoMsgObj.SetTime(STime: String);
  384.   Begin
  385.   FM^.QTime := Copy(STime,1,5);
  386.   PutNullStr(Copy(STime + ':00', 1, 8), 155);
  387.   End;
  388.  
  389.  
  390. Procedure FidoMsgObj.SetLocal(LS: Boolean);
  391.   Begin
  392.   If LS Then
  393.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 1)
  394.   Else
  395.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 1));
  396.   End;
  397.  
  398.  
  399. Procedure FidoMsgObj.SetRcvd(RS: Boolean);
  400.   Begin
  401.   If RS Then
  402.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 4)
  403.   Else
  404.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 4));
  405.   End;
  406.  
  407.  
  408. Procedure FidoMsgObj.SetPriv(PS: Boolean);
  409.   Begin
  410.   If PS Then
  411.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 1)
  412.   Else
  413.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 1));
  414.   End;
  415.  
  416.  
  417. Procedure FidoMsgObj.SetCrash(SS: Boolean);
  418.   Begin
  419.   If SS Then
  420.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 2)
  421.   Else
  422.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 2));
  423.   End;
  424.  
  425.  
  426. Procedure FidoMsgObj.SetKillSent(SS: Boolean);
  427.   Begin
  428.   If SS Then
  429.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 128)
  430.   Else
  431.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 128));
  432.   End;
  433.  
  434.  
  435. Procedure FidoMsgObj.SetSent(SS: Boolean);
  436.   Begin
  437.   If SS Then
  438.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 8)
  439.   Else
  440.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 8));
  441.   End;
  442.  
  443.  
  444. Procedure FidoMsgObj.SetFAttach(SS: Boolean);
  445.   Begin
  446.   If SS Then
  447.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 16)
  448.   Else
  449.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 16));
  450.   End;
  451.  
  452.  
  453. Procedure FidoMsgObj.SetReqRct(SS: Boolean);
  454.   Begin
  455.   If SS Then
  456.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 16)
  457.   Else
  458.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 16));
  459.   End;
  460.  
  461.  
  462. Procedure FidoMsgObj.SetReqAud(SS: Boolean);
  463.   Begin
  464.   If SS Then
  465.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 64)
  466.   Else
  467.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 64));
  468.   End;
  469.  
  470.  
  471. Procedure FidoMsgObj.SetRetRct(SS: Boolean);
  472.   Begin
  473.   If SS Then
  474.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 32)
  475.   Else
  476.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 32));
  477.   End;
  478.  
  479.  
  480. Procedure FidoMsgObj.SetFileReq(SS: Boolean);
  481.   Begin
  482.   If SS Then
  483.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 8)
  484.   Else
  485.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 8));
  486.   End;
  487.  
  488.  
  489. Procedure FidoMsgObj.DoString(Str: String);
  490.   Var
  491.     i: Word;
  492.  
  493.   Begin
  494.   i := 1;
  495.   While i <= Length(Str) Do
  496.     Begin
  497.     DoChar(Str[i]);
  498.     Inc(i);
  499.     End;
  500.   End;
  501.  
  502.  
  503. Procedure FidoMsgObj.DoChar(Ch: Char);
  504.   Begin
  505.   If FM^.TextCtr < SizeOf(FM^.MsgChars) Then
  506.     Begin
  507.     FM^.MsgChars[FM^.TextCtr] := Ch;
  508.     Inc(FM^.TextCtr);
  509.     End;
  510.   End;
  511.  
  512.  
  513. Procedure FidoMsgObj.DoStringLn(Str: String);
  514.   Begin
  515.   DoString(Str);
  516.   DoChar(#13);
  517.   End;
  518.  
  519.  
  520. Function  FidoMsgObj.WriteMsg: Word;
  521.   Var
  522.     NetNum: Word;
  523.     TmpDate: LongInt;
  524.     {$IFDEF WINDOWS}
  525.     TmpDT: TDateTime;
  526.     {$ELSE}
  527.     TmpDT: DateTime;
  528.     {$ENDIF}
  529.  
  530.  
  531.   Begin
  532.   NetNum := GetHighMsgNum + 1;
  533.   PutLong(GetDosDate, 180);
  534.   TmpDT.Year := Str2Long(Copy(FM^.QDate,7,2));
  535.   If TmpDT.Year > 79 Then
  536.     Inc(TmpDT.Year, 1900)
  537.   Else
  538.     Inc(TmpDT.Year, 2000);
  539.   TmpDT.Month := Str2Long(Copy(FM^.QDate,1,2));
  540.   TmpDT.Day := Str2Long(Copy(FM^.QDate,4,2));
  541.   TmpDt.Hour := Str2Long(Copy(FM^.QTime,1,2));
  542.   TmpDt.Min := Str2Long(Copy(FM^.QTime, 4,2));
  543.   TmpDt.Sec := 0;
  544.   PackTime(TmpDT, TmpDate);
  545.   PutLong(TmpDate, 176);
  546.   Assign(FM^.MsgFile, FM^.NetMailPath + Long2Str(NetNum) + '.Msg');
  547.   ReWrite(FM^.MsgFile,1);
  548.   BlockWrite(FM^.MsgFile, FM^.MsgChars, FM^.TextCtr + 1);
  549.   Close(FM^.MsgFile);
  550.   FM^.CurrMsg := NetNum;
  551.   WriteMsg := IoResult;
  552.   End;
  553.  
  554.  
  555. Procedure FidoMsgObj.SetDefaultZone(DZ: Word); {Set default zone to use}
  556.   Begin
  557.   FM^.DefaultZone := DZ;
  558.   End;
  559.  
  560.  
  561. Procedure FidoMsgObj.LineStart;
  562.   Begin
  563.   If FM^.MsgChars[FM^.TextCtr] = #10 Then
  564.     Inc(FM^.TextCtr);
  565.   If FM^.MsgChars[FM^.TextCtr] = #1 Then
  566.     Inc(FM^.TextCtr);
  567.   End;
  568.  
  569.  
  570. Function FidoMsgObj.GetChar: Char;
  571.   Begin
  572.   If ((FM^.TextCtr >= FM^.MsgSize) Or (FM^.MsgChars[FM^.TextCtr] = #0)) Then
  573.     Begin
  574.     GetChar := #0;
  575.     FM^.MsgDone := True;
  576.     End
  577.   Else
  578.     Begin
  579.     GetChar := FM^.MsgChars[FM^.TextCtr];
  580.     Inc(FM^.TextCtr);
  581.     End;
  582.   End;
  583.  
  584.  
  585. Procedure FidoMsgObj.CheckZone(ZoneStr: String);
  586.   Var
  587.     DestZoneStr: String;
  588.     Code: Word;
  589.  
  590.   Begin
  591.   If (Upper(Copy(ZoneStr,1,4)) = 'INTL') Then
  592.     Begin
  593.     DestZoneStr := ExtractWord(ZoneStr, 2);
  594.     DestZoneStr := StripBoth(DestZoneStr, ' ');
  595.     DestZoneStr := Copy(DestZoneStr, 1, Pos(':', DestZoneStr) - 1);
  596.     Val(DestZoneStr, FM^.Dest.Zone, Code);
  597.     DestZoneStr := ExtractWord(ZoneStr,3);
  598.     DestZoneStr := StripBoth(DestZoneStr, ' ');
  599.     DestZoneStr := Copy(DestZoneStr, 1, Pos(':', DestZoneStr) - 1);
  600.     Val(DestZoneStr, FM^.Orig.Zone, Code);
  601.     End;
  602.   End;
  603.  
  604.  
  605. Procedure FidoMsgObj.CheckPoint(PointStr: String);
  606.   Var
  607.     DestPointStr: String;
  608.     Code: Word;
  609.     Temp: Word;
  610.  
  611.   Begin
  612.   If (Upper(Copy(PointStr,1,4)) = 'TOPT') Then
  613.     Begin
  614.     DestPointStr := ExtractWord(PointStr, 2);
  615.     DestPointStr := StripBoth(DestPointStr, ' ');
  616.     Val(DestPointStr, Temp, Code);
  617.     If Code = 0 Then
  618.       FM^.Dest.Point := Temp;
  619.     End;
  620.   If (Upper(Copy(PointStr,1,4)) = 'FMPT') Then
  621.     Begin
  622.     DestPointStr := ExtractWord(PointStr, 2);
  623.     DestPointStr := StripBoth(DestPointStr, ' ');
  624.     Val(DestPointStr, Temp, Code);
  625.     If Code = 0 Then
  626.       FM^.Orig.Point := Temp;
  627.     End;
  628.   End;
  629.  
  630.  
  631. Function MonthNum(St: String):Word;
  632.   Begin
  633.   ST := Upper(St);
  634.   MonthNum := 0;
  635.   If St = 'JAN' Then MonthNum := 01;
  636.   If St = 'FEB' Then MonthNum := 02;
  637.   If St = 'MAR' Then MonthNum := 03;
  638.   If St = 'APR' Then MonthNum := 04;
  639.   If St = 'MAY' Then MonthNum := 05;
  640.   If St = 'JUN' Then MonthNum := 06;
  641.   If St = 'JUL' Then MonthNum := 07;
  642.   If St = 'AUG' Then MonthNum := 08;
  643.   If St = 'SEP' Then MonthNum := 09;
  644.   If St = 'OCT' Then MonthNum := 10;
  645.   If St = 'NOV' Then MonthNum := 11;
  646.   If St = 'DEC' Then MonthNum := 12;
  647.   End;
  648.  
  649.  
  650. Function FidoMsgObj.CvtDate: Boolean;
  651.   Var
  652.     MoNo: Word;
  653.     TmpStr: String;
  654.     i: Word;
  655.     MsgDt: String[25];
  656.  
  657.   Begin
  658.   MsgDt := BufferNullString(144, 20);
  659.   MsgDt := PadRight(MsgDt,' ', 20);
  660.   CvtDate := True;
  661.   If MsgDt[3] = ' ' Then
  662.     Begin {Fido or Opus}
  663.     If MsgDt[11] = ' ' Then
  664.       Begin {Fido DD MON YY  HH:MM:SSZ}
  665.       FM^.QTime := Copy (MsgDT,12,5);
  666.       TmpStr := Long2Str(MonthNum(Copy(MsgDt,4,3)));
  667.       If Length(TmpStr) = 1 Then
  668.         TmpStr := '0' + TmpStr;
  669.       FM^.QDate := TmpStr + '-' + Copy(MsgDT,1,2) + '-' + Copy (MsgDt,8,2);
  670.       End
  671.     Else
  672.       Begin {Opus DD MON YY HH:MM:SS}
  673.       FM^.QTime := Copy(MsgDT,11,5);
  674.       TmpStr := Long2Str(MonthNum(Copy(MsgDt,4,3)));
  675.       If Length(TmpStr) = 1 Then
  676.         TmpStr := '0' + TmpStr;
  677.       FM^.QDate := TmpStr + '-' + Copy(MsgDT,1,2) + '-' + Copy (MsgDt,8,2);
  678.       End;
  679.     End
  680.   Else
  681.     Begin
  682.     If MsgDT[4] = ' ' Then
  683.       Begin {SeaDog format DOW DD MON YY HH:MM}
  684.       FM^.QTime := Copy(MsgDT,15,5);
  685.       TmpStr := Long2Str(MonthNum(Copy(MsgDT,8,3)));
  686.       If Length(TmpStr) = 1 Then
  687.         TmpStr := '0' + TmpStr;
  688.       FM^.QDate := TmpStr + '-' + Copy(MsgDT,5,2) + '-' + Copy (MsgDt,12,2);
  689.       End
  690.     Else
  691.       Begin
  692.       If MsgDT[3] = '-' Then
  693.         Begin {Wierd format DD-MM-YYYY HH:MM:SS}
  694.         FM^.QTime := Copy(MsgDt,12,5);
  695.         FM^.QDate := Copy(MsgDt,4,3) + Copy (MsgDt,1,3) + Copy (MsgDt,9,2);
  696.         End
  697.       Else
  698.         Begin  {Bad Date}
  699.         CvtDate := False;
  700.         End;
  701.       End;
  702.     End;
  703.   For i := 1 to 5 Do
  704.     If FM^.QTime[i] = ' ' Then
  705.       FM^.QTime[i] := '0';
  706.   For i := 1 to 8 Do
  707.     If FM^.QDate[i] = ' ' Then
  708.       FM^.QDate[i] := '0';
  709.   If Length(FM^.QDate) <> 8 Then
  710.     CvtDate := False;
  711.   If Length(FM^.QTime) <> 5 Then
  712.     CvtDate := False;
  713.   End;
  714.  
  715.  
  716. Function FidoMsgObj.BufferWord(i: Word):Word;
  717.   Begin
  718.   BufferWord := BufferByte(i) + (BufferByte(i + 1) shl 8);
  719.   End;
  720.  
  721.  
  722. Function FidoMsgObj.BufferByte(i: Word):Byte;
  723.   Begin
  724.   BufferByte := Ord(FM^.MsgChars[i]);
  725.   End;
  726.  
  727.  
  728. Function FidoMsgObj.BufferNullString(i: Word; Max: Word): String;
  729.   Var
  730.     Ctr: Word;
  731.     CurrPos: Word;
  732.  
  733.   Begin
  734.   BufferNullString := '';
  735.   Ctr := i;
  736.   CurrPos := 0;
  737.   While ((CurrPos < Max) and (FM^.MsgChars[Ctr] <> #0)) Do
  738.     Begin
  739.     Inc(CurrPos);
  740.     BufferNullString[CurrPos] := FM^.MsgChars[Ctr];
  741.     Inc(Ctr);
  742.     End;
  743.   BufferNullString[0] := Chr(CurrPos);
  744.   End;
  745.  
  746.  
  747. Procedure FidoMsgObj.CheckLine(TStr: String);
  748.   Begin
  749.   If TStr[1] = #10 Then
  750.     TStr := Copy(TStr,2,255);
  751.   If TStr[1] = #01 Then
  752.     TStr := Copy(TStr,2,255);
  753.   CheckZone(TStr);
  754.   CheckPoint(TStr);
  755.   End;
  756.  
  757.  
  758. Procedure FidoMsgObj.MsgStartUp;
  759.   Var
  760.     TStr: String;
  761.  
  762.   Begin
  763.   FM^.LastSoft := False;
  764.   If FileExist (FM^.NetMailPath + Long2Str(FM^.CurrMsg) + '.MSG') Then
  765.     FM^.Error := 0
  766.   Else
  767.     FM^.Error := 200;
  768.   If FM^.Error = 0 Then
  769.     Begin
  770.     If Not shAssign(FM^.MsgFile, FM^.NetMailPath +
  771.       Long2Str(FM^.CurrMsg) + '.MSG')  Then
  772.       FM^.Error := FileError;
  773.     End;
  774.   If FM^.Error = 0 Then
  775.     Begin
  776.     FileMode := fmReadWrite + fmDenyNone;
  777.     If Not shReset(FM^.MsgFile, 1) Then
  778.       FM^.Error := FileError;
  779.     End;
  780.   FillChar(FM^.MsgChars, SizeOf(FM^.MsgChars), 0);
  781.   If FM^.Error = 0 Then
  782.     Begin
  783.     If Not shRead(FM^.MsgFile, FM^.MsgChars, SizeOf(FM^.MsgChars), FM^.MsgSize) Then
  784.       FM^.Error := FileError;
  785.     End;
  786.   Close(FM^.MsgFile);
  787.   If IoResult <> 0 Then;
  788.   FM^.MsgDone := False;
  789.   FM^.MsgEnd := 0;
  790.   FM^.MsgStart := 190;
  791.   FM^.Dest.Zone := FM^.DefaultZone;
  792.   FM^.Dest.Point := 0;
  793.   FM^.Orig.Zone := FM^.DefaultZone;
  794.   FM^.Orig.Point := 0;
  795.   FM^.Orig.Net := BufferWord(172);
  796.   FM^.Orig.Node := BufferWord(168);
  797.   FM^.Dest.Net := BufferWord(174);
  798.   FM^.Dest.Node := BufferWord(166);
  799.   FM^.TextCtr := FM^.MsgStart;
  800.   If Not CvtDate Then
  801.     Begin
  802.     FM^.QDate := '09-06-89';
  803.     FM^.QTime := '19:76';
  804.     End;
  805.   TStr := GetString(128);
  806.   CheckLine(TStr);
  807.   While ((FM^.MsgEnd = 0) and (FM^.TextCtr <= FM^.MsgSize)) Do
  808.     Begin
  809.     While ((FM^.MsgChars[FM^.TextCtr] <> #0) and (FM^.MsgChars[FM^.TextCtr] <> #13)) Do
  810.       Inc(FM^.TextCtr);
  811.     If FM^.MsgChars[FM^.TextCtr] = #0 Then
  812.       Begin
  813.       FM^.MsgEnd := FM^.TextCtr - 1;
  814.       End
  815.     Else
  816.       Begin
  817.       Inc(FM^.TextCtr);
  818.       TStr := GetString(128);
  819.       CheckLine(TStr);
  820.       End;
  821.     End;
  822.   If FM^.MsgEnd = 0 Then
  823.     FM^.MsgEnd := FM^.MsgSize;
  824.   FM^.MsgSize := FM^.MsgEnd;
  825.   FM^.MsgStart := 190;
  826.   FM^.TextCtr := FM^.MsgStart;
  827.   FM^.MsgDone := False;
  828.   FM^.LastSoft := False;
  829.   End;
  830.  
  831.  
  832. Procedure FidoMsgObj.MsgTxtStartUp;
  833.   Begin
  834.   FM^.MsgStart := 190;
  835.   FM^.TextCtr := FM^.MsgStart;
  836.   FM^.MsgDone := False;
  837.   FM^.LastSoft := False;
  838.   End;
  839.  
  840.  
  841. Function FidoMsgObj.GetString(MaxLen: Word): String;
  842.   Var
  843.     WPos: Word;
  844.     WLen: Byte;
  845.     StrDone: Boolean;
  846.     TxtOver: Boolean;
  847.     StartSoft: Boolean;
  848.     CurrLen: Word;
  849.     PPos: Word;
  850.     TmpCh: Char;
  851.  
  852.   Begin
  853.   StrDone := False;
  854.   CurrLen := 0;
  855.   PPos := FM^.TextCtr;
  856.   WPos := 0;
  857.   WLen := 0;
  858.   StartSoft := FM^.LastSoft;
  859.   FM^.LastSoft := True;
  860.   TmpCh := GetChar;
  861.   While ((Not StrDone) And (CurrLen < MaxLen) And (Not FM^.MsgDone)) Do
  862.     Begin
  863.     Case TmpCh of
  864.       #$00:;
  865.       #$0d: Begin
  866.             StrDone := True;
  867.             FM^.LastSoft := False;
  868.             End;
  869.       #$8d:;
  870.       #$0a:;
  871.       #$20: Begin
  872.             If ((CurrLen <> 0) or (Not StartSoft)) Then
  873.               Begin
  874.               Inc(CurrLen);
  875.               WLen := CurrLen;
  876.               GetString[CurrLen] := TmpCh;
  877.               WPos := FM^.TextCtr;
  878.               End
  879.             Else
  880.               StartSoft := False;
  881.             End;
  882.       Else
  883.         Begin
  884.         Inc(CurrLen);
  885.         GetString[CurrLen] := TmpCh;
  886.         End;
  887.       End;
  888.     If Not StrDone Then
  889.       TmpCh := GetChar;
  890.     End;
  891.   If StrDone Then
  892.     Begin
  893.     GetString[0] := Chr(CurrLen);
  894.     End
  895.   Else
  896.     If FM^.MsgDone Then
  897.       Begin
  898.       GetString[0] := Chr(CurrLen);
  899.       End
  900.     Else
  901.       Begin
  902.       If WLen = 0 Then
  903.         Begin
  904.         GetString[0] := Chr(CurrLen);
  905.         Dec(FM^.TextCtr);
  906.         End
  907.       Else
  908.         Begin
  909.         GetString[0] := Chr(WLen);
  910.         FM^.TextCtr := WPos;
  911.         End;
  912.       End;
  913.   End;
  914.  
  915.  
  916. Function FidoMsgObj.EOM: Boolean;
  917.   Begin
  918.   EOM := FM^.MsgDone;
  919.   End;
  920.  
  921.  
  922. Function FidoMsgObj.WasWrap: Boolean;
  923.   Begin
  924.   WasWrap := FM^.LastSoft;
  925.   End;
  926.  
  927.  
  928. Function FidoMsgObj.GetFrom: String; {Get from name on current msg}
  929.   Begin
  930.   GetFrom := BufferNullString(0, 35);
  931.   End;
  932.  
  933.  
  934. Function FidoMsgObj.GetTo: String; {Get to name on current msg}
  935.   Begin
  936.   GetTo := BufferNullString(36,35);
  937.   End;
  938.  
  939.  
  940. Function FidoMsgObj.GetSubj: String; {Get subject on current msg}
  941.   Begin
  942.   GetSubj := BufferNullString(72,71);
  943.   End;
  944.  
  945.  
  946. Function FidoMsgObj.GetCost: Word; {Get cost of current msg}
  947.   Begin
  948.   GetCost := BufferWord(170);
  949.   End;
  950.  
  951.  
  952. Function FidoMsgObj.GetDate: String; {Get date of current msg}
  953.   Begin
  954.   GetDate := FM^.QDate;
  955.   End;
  956.  
  957.  
  958. Function FidoMsgObj.GetTime: String; {Get time of current msg}
  959.   Begin
  960.   GetTime := FM^.QTime;
  961.   End;
  962.  
  963.  
  964. Function FidoMsgObj.GetRefer: LongInt; {Get reply to of current msg}
  965.   Begin
  966.   GetRefer := BufferWord(184);
  967.   End;
  968.  
  969.  
  970. Function FidoMsgObj.GetSeeAlso: LongInt; {Get see also of current msg}
  971.   Begin
  972.   GetSeeAlso := BufferWord(188);
  973.   End;
  974.  
  975.  
  976. Function FidoMsgObj.GetMsgNum: LongInt; {Get message number}
  977.   Begin
  978.   GetMsgNum := FM^.CurrMsg;
  979.   End;
  980.  
  981.  
  982. Procedure FidoMsgObj.GetOrig(Var Addr: AddrType); {Get origin address}
  983.   Begin
  984.   Addr := FM^.Orig;
  985.   End;
  986.  
  987.  
  988. Procedure FidoMsgObj.GetDest(Var Addr: AddrType); {Get destination address}
  989.   Begin
  990.   Addr := FM^.Dest;
  991.   End;
  992.  
  993.  
  994. Function FidoMsgObj.IsLocal: Boolean; {Is current msg local}
  995.   Begin
  996.   IsLocal := ((Ord(FM^.MsgChars[187]) and 001) <> 0);
  997.   End;
  998.  
  999.  
  1000. Function FidoMsgObj.IsCrash: Boolean; {Is current msg crash}
  1001.   Begin
  1002.   IsCrash := ((Ord(FM^.MsgChars[186]) and 002) <> 0);
  1003.   End;
  1004.  
  1005.  
  1006. Function FidoMsgObj.IsKillSent: Boolean; {Is current msg kill sent}
  1007.   Begin
  1008.   IsKillSent := ((Ord(FM^.MsgChars[186]) and 128) <> 0);
  1009.   End;
  1010.  
  1011.  
  1012. Function FidoMsgObj.IsSent: Boolean; {Is current msg sent}
  1013.   Begin
  1014.   IsSent := ((Ord(FM^.MsgChars[186]) and 008) <> 0);
  1015.   End;
  1016.  
  1017.  
  1018. Function FidoMsgObj.IsFAttach: Boolean; {Is current msg file attach}
  1019.   Begin
  1020.   IsFAttach := ((Ord(FM^.MsgChars[186]) and 016) <> 0);
  1021.   End;
  1022.  
  1023.  
  1024. Function FidoMsgObj.IsReqRct: Boolean; {Is current msg request receipt}
  1025.   Begin
  1026.   IsReqRct := ((Ord(FM^.MsgChars[187]) and 016) <> 0);
  1027.   End;
  1028.  
  1029.  
  1030. Function FidoMsgObj.IsReqAud: Boolean; {Is current msg request audit}
  1031.   Begin
  1032.   IsReqAud := ((Ord(FM^.MsgChars[187]) and 064) <> 0);
  1033.   End;
  1034.  
  1035.  
  1036. Function FidoMsgObj.IsRetRct: Boolean; {Is current msg a return receipt}
  1037.   Begin
  1038.   IsRetRct := ((Ord(FM^.MsgChars[187]) and 032) <> 0);
  1039.   End;
  1040.  
  1041.  
  1042. Function FidoMsgObj.IsFileReq: Boolean; {Is current msg a file request}
  1043.   Begin
  1044.   IsFileReq := ((Ord(FM^.MsgChars[187]) and 008) <> 0);
  1045.   End;
  1046.  
  1047.  
  1048. Function FidoMsgObj.IsRcvd: Boolean; {Is current msg received}
  1049.   Begin
  1050.   IsRcvd := ((Ord(FM^.MsgChars[186]) and 004) <> 0);
  1051.   End;
  1052.  
  1053.  
  1054. Function FidoMsgObj.IsPriv: Boolean; {Is current msg priviledged/private}
  1055.   Begin
  1056.   IsPriv := ((Ord(FM^.MsgChars[186]) and 001) <> 0);
  1057.   End;
  1058.  
  1059.  
  1060. Function FidoMsgObj.IsDeleted: Boolean; {Is current msg deleted}
  1061.   Begin
  1062.   IsDeleted := False;
  1063.   End;
  1064.  
  1065.  
  1066. Function FidoMsgObj.IsEchoed: Boolean; {Is current msg echoed}
  1067.   Begin
  1068.   IsEchoed := True;
  1069.   End;
  1070.  
  1071.  
  1072. Procedure FidoMsgObj.SeekFirst(MsgNum: LongInt); {Start msg seek}
  1073.   Begin
  1074.   FM^.CurrMsg := MsgNum - 1;
  1075.   SeekNext;
  1076.   End;
  1077.  
  1078.  
  1079. Procedure FidoMsgObj.SeekNext; {Find next matching msg}
  1080.   Var
  1081.     Code: Word;
  1082.     BestMatch: LongInt;
  1083.     CurrTry : LongInt;
  1084.     {$IFDEF WINDOWS}
  1085.       TStr: Array[0..128] of Char;
  1086.     {$ENDIF}
  1087.     MsgWasFound: Boolean;
  1088.  
  1089.   Begin
  1090.   CurrTry := 0;
  1091.   MsgWasFound := False;
  1092.   BestMatch := $7fffffff;
  1093.   Inc(FM^.CurrMsg);
  1094.   {$IFDEF WINDOWS}
  1095.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  1096.   FindFirst(TStr, faReadOnly + faArchive, FM^.SR);
  1097.   {$ELSE}
  1098.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, FM^.SR);
  1099.   {$ENDIF}
  1100.   While DosError = 0 Do
  1101.     Begin
  1102.     {$IFDEF WINDOWS}
  1103.       FM^.MsgName := StrPas(FM^.SR.Name);
  1104.     {$ELSE}
  1105.       FM^.MsgName := FM^.SR.Name;
  1106.     {$ENDIF}
  1107.     Val(Copy(FM^.MsgName, 1, Pos('.', FM^.MsgName) - 1), CurrTry, Code);
  1108.     If Code = 0 Then
  1109.       Begin
  1110.       If ((CurrTry >= FM^.CurrMsg) and (CurrTry < BestMatch)) Then
  1111.         Begin
  1112.         BestMatch := CurrTry;
  1113.         MsgWasFound := True;
  1114.         End;
  1115.       End;
  1116.     FindNext(FM^.SR);
  1117.     End;
  1118.   If MsgWasFound Then
  1119.     FM^.CurrMsg := BestMatch
  1120.   Else
  1121.     FM^.CurrMsg := 0;
  1122.   End;
  1123.  
  1124.  
  1125. Procedure FidoMsgObj.SeekPrior;
  1126.   Var
  1127.     Code: Word;
  1128.     BestMatch: LongInt;
  1129.     CurrTry : LongInt;
  1130.     {$IFDEF WINDOWS}
  1131.       TStr: Array[0..128] of Char;
  1132.     {$ENDIF}
  1133.     MsgWasFound: Boolean;
  1134.  
  1135.   Begin
  1136.   CurrTry := 0;
  1137.   MsgWasFound := False;
  1138.   BestMatch := 0;
  1139.   Dec(FM^.CurrMsg);
  1140.   {$IFDEF WINDOWS}
  1141.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  1142.   FindFirst(TStr, faReadOnly + faArchive, FM^.SR);
  1143.   {$ELSE}
  1144.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, FM^.SR);
  1145.   {$ENDIF}
  1146.   While DosError = 0 Do
  1147.     Begin
  1148.     {$IFDEF WINDOWS}
  1149.       FM^.MsgName := StrPas(FM^.SR.Name);
  1150.     {$ELSE}
  1151.       FM^.MsgName := FM^.SR.Name;
  1152.     {$ENDIF}
  1153.     Val(Copy(FM^.MsgName, 1, Pos('.', FM^.MsgName) - 1), CurrTry, Code);
  1154.     If Code = 0 Then
  1155.       Begin
  1156.       If ((CurrTry <= FM^.CurrMsg) and (CurrTry > BestMatch)) Then
  1157.         Begin
  1158.         BestMatch := CurrTry;
  1159.         MsgWasFound := True;
  1160.         End;
  1161.       End;
  1162.     FindNext(FM^.SR);
  1163.     End;
  1164.   If MsgWasFound Then
  1165.     FM^.CurrMsg := BestMatch
  1166.   Else
  1167.     FM^.CurrMsg := 0;
  1168.   End;
  1169.  
  1170.  
  1171. Function FidoMsgObj.SeekFound: Boolean;
  1172.   Begin
  1173.   SeekFound := FM^.CurrMsg <> 0;
  1174.   End;
  1175.  
  1176.  
  1177. Function FidoMsgObj.GetMsgLoc: LongInt; {Msg location}
  1178.   Begin
  1179.   GetMsgLoc := GetMsgNum;
  1180.   End;
  1181.  
  1182.  
  1183. Procedure FidoMsgObj.SetMsgLoc(ML: LongInt); {Msg location}
  1184.   Begin
  1185.   FM^.CurrMsg := ML;
  1186.   End;
  1187.  
  1188.  
  1189. Procedure FidoMsgObj.YoursFirst(Name: String; Handle: String);
  1190.   Begin
  1191.   FM^.Name := Upper(Name);
  1192.   FM^.Handle := Upper(Handle);
  1193.   FM^.CurrMsg := 0;
  1194.   YoursNext;
  1195.   End;
  1196.  
  1197.  
  1198. Procedure FidoMsgObj.YoursNext;
  1199.   Var
  1200.     FoundDone: Boolean;
  1201.  
  1202.   Begin
  1203.   FoundDone := False;
  1204.   SeekFirst(FM^.CurrMsg + 1);
  1205.   While ((FM^.CurrMsg <> 0) And (Not FoundDone)) Do
  1206.     Begin
  1207.     MsgStartUp;
  1208.     If ((Upper(GetTo) = FM^.Name) Or (Upper(GetTo) = FM^.Handle)) Then
  1209.       FoundDone := True;
  1210.     If IsRcvd Then FoundDone := False;
  1211.     If Not FoundDone Then
  1212.       SeekNext;
  1213.     If Not SeekFound Then
  1214.       FoundDone := True;
  1215.     End;
  1216.   End;
  1217.  
  1218.  
  1219. Function FidoMsgObj.YoursFound: Boolean;
  1220.   Begin
  1221.   YoursFound := SeekFound;
  1222.   End;
  1223.  
  1224.  
  1225. Procedure FidoMsgObj.StartNewMsg;
  1226.   Begin
  1227.   FillChar(FM^.MsgChars, SizeOf(FM^.MsgChars), #0);
  1228.   FM^.TextCtr := 190;
  1229.   FM^.Dest.Zone := 0;
  1230.   FM^.Orig.Zone := 0;
  1231.   FM^.Dest.Point := 0;
  1232.   FM^.Orig.Point := 0;
  1233.   End;
  1234.  
  1235.  
  1236. Function FidoMsgObj.OpenMsgBase: Word;
  1237.   Begin
  1238.   OpenMsgBase := 0;
  1239.   End;
  1240.  
  1241.  
  1242. Function FidoMsgObj.CloseMsgBase: Word;
  1243.   Begin
  1244.   CloseMsgBase := 0;
  1245.   End;
  1246.  
  1247.  
  1248. Function FidoMsgObj.CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word;
  1249.   Begin
  1250.   CreateMsgBase := 0;
  1251.   End;
  1252.  
  1253.  
  1254. Procedure FidoMsgObj.SetMailType(MT: MsgMailType);
  1255.   Begin
  1256.   End;
  1257.  
  1258.  
  1259. Function FidoMsgObj.GetSubArea: Word;
  1260.   Begin
  1261.   GetSubArea := 0;
  1262.   End;
  1263.  
  1264.  
  1265. Procedure FidoMsgObj.ReWriteHdr;
  1266.   Var
  1267.     NetNum: LongInt;
  1268.  
  1269.   Begin
  1270.   NetNum := FM^.CurrMsg;
  1271.   Assign(FM^.MsgFile, FM^.NetMailPath + Long2Str(NetNum) + '.Msg');
  1272.   ReWrite(FM^.MsgFile,1);
  1273.   BlockWrite(FM^.MsgFile, FM^.MsgChars, FM^.TextCtr + 1);
  1274.   Close(FM^.MsgFile);
  1275.   End;
  1276.  
  1277.  
  1278. Procedure FidoMsgObj.DeleteMsg;
  1279.   Begin
  1280.   Assign(FM^.MsgFile, FM^.NetMailPath + Long2Str(FM^.CurrMsg) + '.MSG');
  1281.   Erase(FM^.MsgFile);
  1282.   If IoResult <> 0 Then;
  1283.   End;
  1284.  
  1285.  
  1286. Function FidoMsgObj.NumberOfMsgs: LongInt;
  1287.   Var
  1288.   {$IFDEF WINDOWS}
  1289.     SR: TSearchRec;
  1290.     TStr: Array[0..128] of Char;
  1291.   {$ELSE}
  1292.     SR: SearchRec;
  1293.   {$ENDIF}
  1294.   TmpName: String[13];
  1295.   TmpNum: Word;
  1296.   Code: Word;
  1297.   Active: LongInt;
  1298.  
  1299.   Begin
  1300.   Active := 0;
  1301.   {$IFDEF WINDOWS}
  1302.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  1303.   FindFirst(TStr, faReadOnly + faArchive, SR);
  1304.   {$ELSE}
  1305.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, SR);
  1306.   {$ENDIF}
  1307.   While DosError = 0 Do
  1308.     Begin
  1309.     {$IFDEF WINDOWS}
  1310.     TmpName :=  StrPas(SR.Name);
  1311.     {$ELSE}
  1312.     TmpName := SR.Name;
  1313.     {$ENDIF}
  1314.     Val(Copy(TmpName, 1,  Pos('.', TmpName) -1), TmpNum, Code);
  1315.     If (Code = 0) Then
  1316.       Inc(Active);
  1317.     FindNext(SR);
  1318.     End;
  1319.   NumberOfMsgs := Active;
  1320.   End;
  1321.  
  1322.  
  1323. Function FidoMsgObj.GetLastRead(UNum: LongInt): LongInt;
  1324.   Var
  1325.     LRec: Word;
  1326.  
  1327.   Begin
  1328.   If ((UNum + 1) * SizeOf(LRec)) >
  1329.   SizeFile(FM^.NetMailPath + 'LastRead') Then
  1330.     GetLastRead := 0
  1331.   Else
  1332.     Begin
  1333.     If LoadFilePos(FM^.NetMailPath + 'LastRead', LRec, SizeOf(LRec),
  1334.     UNum * SizeOf(LRec)) = 0 Then
  1335.       GetLastRead := LRec
  1336.     Else
  1337.       GetLastRead := 0;
  1338.     End;
  1339.   End;
  1340.  
  1341.  
  1342. Procedure FidoMsgObj.SetLastRead(UNum: LongInt; LR: LongInt);
  1343.   Var
  1344.     LRec: Word;
  1345.     Status: Word;
  1346.  
  1347.   Begin
  1348.   If ((UNum + 1) * SizeOf(LRec)) >
  1349.   SizeFile(FM^.NetMailPath + 'LastRead') Then
  1350.     Begin
  1351.     Status := ExtendFile(FM^.NetMailPath + 'LastRead',
  1352.     (UNum + 1) * SizeOf(LRec));
  1353.     End;
  1354.   If LoadFilePos(FM^.NetMailPath + 'LastRead', LRec, SizeOf(LRec),
  1355.   UNum * SizeOf(LRec)) = 0 Then
  1356.     Begin
  1357.     LRec := LR;
  1358.     Status := SaveFilePos(FM^.NetMailPath + 'LastRead', LRec, SizeOf(LRec),
  1359.     UNum * SizeOf(LRec));
  1360.     End;
  1361.   End;
  1362.  
  1363.  
  1364. Function FidoMsgObj.GetTxtPos: LongInt;
  1365.   Begin
  1366.   GetTxtPos := FM^.TextCtr;
  1367.   End;
  1368.  
  1369.  
  1370. Procedure FidoMsgObj.SetTxtPos(TP: LongInt);
  1371.   Begin
  1372.   FM^.TextCtr := TP;
  1373.   End;
  1374.  
  1375.  
  1376. End.
  1377.